package com.yonyou.cyxdms.basedata.service.util;

import cn.afterturn.easypoi.handler.inter.IExcelDictHandler;
import com.xiaoleilu.hutool.lang.Assert;
import com.yonyou.cyx.framework.bean.dto.base.ClientInfoDTO;
import com.yonyou.cyx.framework.util.bean.ApplicationContextHelper;
import com.yonyou.cyx.function.exception.ServiceBizException;
import com.yonyou.cyxdms.basedata.client.domains.vo.CodeVO;
import com.yonyou.cyxdms.basedata.client.domains.vo.RegionVO;
import com.yonyou.cyxdms.basedata.client.service.basedata.BaseCommonCodeService;
import com.yonyou.cyxdms.basedata.client.service.basedata.BaseCommonRegionService;
import com.yonyou.cyxdms.basedata.service.constant.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static com.yonyou.cyxdms.basedata.service.constant.CommonConstant.APP_ID_BEIJING;

@Slf4j
public class GlobalExcelDictHandler implements IExcelDictHandler {

    /** 字典缓存 **/
    private static final Map<String, HashMap<String, String>> CASH = new ConcurrentHashMap<>();
    /* 省市区对应字典类型 **/
    private static final String REGION = "REGION";

    /**
     * 导出 value -> name
     *
     * @author lyz
     * @date 2020/11/16
     */
    @Override
    public String toName(String dict, Object obj, String name, Object value) {
        return null != value ? checkDict(dict, null, value.toString(), 0) : "";
    }

    @Override
    public String toValue(String dict, Object obj, String name, Object value) {
        return name;
    }

    /**
     * 清除导出字典缓存
     *
     * @author lyz
     * @date 2021/1/18
     */
    public static void clean() {
        CASH.clear();
    }

    /**
     * 查字典
     *
     * @param type     字典类型
     * @param name     字典name
     * @param value    字典value
     * @param isRefush 是否刷新 0未刷新 1已刷新
     * @author lyz
     * @date 2020/12/1
     */
    public String checkDict(String type, String name, String value, int isRefush) {
        HashMap<String, String> biMap = CASH.get(type);
        if (null == biMap) {
            Assert.isTrue(isRefush != 1, "类型[{}]对应的数据未找到", type);
            refush(type);
            return checkDict(type, name, value, 1);
        }
        /* 根据value获取name **/
        String s = biMap.get(value);
        if (null == s) {
            if (isRefush  == 1) {
                /* 无法翻译返回原字典值 **/
                return value;
            }
            refush(type);
            return checkDict(type, name, value, 1);
        }
        return s;
    }

    /**
     * 刷新type字典缓存
     *
     * @param type 字典类型
     * @author lyz
     * @date 2020/11/16
     */
    public void refush(String type) {
        try {
            if (StringUtils.equalsIgnoreCase(REGION, type)) {
                refushRegion();
            }
            else {
                refushDict(type);
            }
        } catch (IllegalArgumentException e) {
            log.error(e.getMessage(), e);
            throw new ServiceBizException("导出查询[" + type + "]类型数据失败！");
        }
    }

    /**
     * 刷新字典
     *
     * @param type 字典类型，一般4位数字
     * @author lyz
     * @date 2020/12/1
     */
    public void refushDict(String type) {
        ClientInfoDTO loginInfoDto = ApplicationContextHelper.getBeanByType(ClientInfoDTO.class);
        String appId = CommonConstant.APP_ID_BEIJING;
        if (null != loginInfoDto && StringUtils.isNotBlank(loginInfoDto.getAppId())) {
            appId = loginInfoDto.getAppId();
        }
        BaseCommonCodeService bean = ApplicationContextHelper.getBeanByType(BaseCommonCodeService.class);
        List<CodeVO> data = bean.getCodeListByType(type, appId);
        HashMap<String, String> biMap = new HashMap<>(data.stream().collect(Collectors.toMap(codeVO -> codeVO.getCodeId().toString(), CodeVO::getCodeCnDesc)));
        CASH.put(type, biMap);
    }

    /**
     * 刷新组织机构缓存
     *
     * @author lyz
     * @date 2020/12/1
     */
    public void refushRegion() {
        ClientInfoDTO loginInfoDto = ApplicationContextHelper.getBeanByType(ClientInfoDTO.class);
        String appId = CommonConstant.APP_ID_BEIJING;
        if (null != loginInfoDto && StringUtils.isNotBlank(loginInfoDto.getAppId())) {
            appId = loginInfoDto.getAppId();
        }
        BaseCommonRegionService bean = ApplicationContextHelper.getBeanByType(BaseCommonRegionService.class);
        List<RegionVO> data = bean.listAllDataWithoutLogin(appId);
        HashMap<String, String> biMap = new HashMap<>(data.stream().collect(Collectors.toMap(regionVO -> regionVO.getRegionId().toString(), RegionVO::getRegionName)));
        CASH.put(REGION, biMap);
    }

}
